package com.cjh.wechat.core.service.impl;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cjh.wechat.commom.pojo.GetUid;
import com.cjh.wechat.commom.pojo.Group;
import com.cjh.wechat.commom.pojo.Notify;
import com.cjh.wechat.commom.pojo.NotifyGroup;
import com.cjh.wechat.commom.pojo.User;
import com.cjh.wechat.commom.pojo.UserAndGroup;
import com.cjh.wechat.commom.type.ApplyStatus;
import com.cjh.wechat.commom.type.GroupMemberLevel;
import com.cjh.wechat.commom.type.ReadStatus;
import com.cjh.wechat.commom.util.BasicUtil;
import com.cjh.wechat.commom.vo.GroupSearchCondition;
import com.cjh.wechat.commom.vo.MemberVo;
import com.cjh.wechat.commom.vo.MineVo;
import com.cjh.wechat.commom.vo.ResponseVo;
import com.cjh.wechat.commom.vo.SearchGroupResultVo;
import com.cjh.wechat.commom.vo.ShowGroupMemberVo;
import com.cjh.wechat.commom.vo.ShowGroupMemberVo.GourpMemberVo;
import com.cjh.wechat.core.dao.GetUidDao;
import com.cjh.wechat.core.dao.GroupDao;
import com.cjh.wechat.core.dao.NotifyDao;
import com.cjh.wechat.core.dao.NotifyGroupDao;
import com.cjh.wechat.core.dao.UserDao;
import com.cjh.wechat.core.service.GroupService;
import com.cjh.wechat.core.service.UserAndGroupService;

@Service
public class GroupServiceImpl implements GroupService
{
    @Resource
    private UserAndGroupService userAndGroupService;
    @Resource
    private GroupDao            groupDao;
    @Resource
    private NotifyGroupDao      notifyGroupDao;
    @Resource
    private NotifyDao           notifyDao;
    @Resource
    private UserDao             userDao;
    @Resource
    private GetUidDao           getUidDao;
    private final static int    no          = 1;
    private final static String INIT_AVATAR = "../img/user.png";
    
    @Override
    public void refuseInvite(Integer no, String gid)
    {
        // 修改通知状态
        Notify notify = notifyDao.selectByPrimaryKey(no);
        notify.setType(ApplyStatus.REFUSE.value);
        notifyDao.updateByPrimaryKeySelective(notify);
        // 新增群组通知
        NotifyGroup notifyGroup = new NotifyGroup();
        notifyGroup.setContent(notify.getUid() + "拒绝该群");
        notifyGroup.setGid(notify.getFromUid());
        notifyGroup.setFromUid(notify.getUid());
        notifyGroup.setIsRead(ReadStatus.UNREAD.value);
        notifyGroup.setDateTime(BasicUtil.getDateTime());
        notifyGroup.setType(ApplyStatus.SYS.value);
        notifyGroupDao.insertSelective(notifyGroup);
    }
    
    @Override
    public void agreeInvite(Integer no, String gid)
    {
        // 修改通知状态
        Notify notify = notifyDao.selectByPrimaryKey(no);
        notify.setType(ApplyStatus.AGREE.value);
        notifyDao.updateByPrimaryKeySelective(notify);
        // 新增群组通知
        NotifyGroup notifyGroup = new NotifyGroup();
        notifyGroup.setContent(notify.getUid() + "已加入该群");
        notifyGroup.setGid(notify.getFromUid());
        notifyGroup.setFromUid(notify.getUid());
        notifyGroup.setIsRead(ReadStatus.UNREAD.value);
        notifyGroup.setDateTime(BasicUtil.getDateTime());
        notifyGroup.setType(ApplyStatus.SYS.value);
        notifyGroupDao.insertSelective(notifyGroup);
        // 群员添加
        UserAndGroup userAndGroup = new UserAndGroup();
        userAndGroup.setGid(notifyGroup.getGid());
        userAndGroup.setNo(no);
        userAndGroup.setType(GroupMemberLevel.USER.value);
        userAndGroup.setUid(notifyGroup.getFromUid());
        userAndGroupService.insert(userAndGroup);
    }
    
    @Override
    public String addGroup(String uid, String name) throws Exception
    {
        GetUid getUid = getUidDao.selectByPrimaryKey(no);
        String gid = getUid.getUid() + "";
        Group group = new Group();
        group.setAvatar(INIT_AVATAR);
        group.setId(gid);
        group.setName(name);
        groupDao.insertSelective(group);
        UserAndGroup userAndGroup = new UserAndGroup();
        userAndGroup.setGid(gid);
        userAndGroup.setUid(uid);
        userAndGroup.setType(GroupMemberLevel.CREATOR.value);
        userAndGroupService.insert(userAndGroup);
        return gid;
    }
    
    @Override
    public ShowGroupMemberVo showGroupMember(String id, String groupId)
    {
        UserAndGroup userAndGroup = userAndGroupService.findByUidAndGid(id, groupId);
        List<User> users = userAndGroupService.findByGroupId(groupId);
        List<GourpMemberVo> members = new ArrayList<GourpMemberVo>();
        for (User user : users)
        {
            UserAndGroup u = userAndGroupService.findByUidAndGid(user.getId(), groupId);
            GourpMemberVo member = new GourpMemberVo();
            member.setAvatar(user.getAvatar());
            member.setId(user.getId());
            member.setNo(user.getNo());
            member.setSign(user.getSign());
            member.setStatus(user.getStatus());
            member.setType(u.getType());
            member.setUsername(user.getUsername());
            members.add(member);
        }
        ShowGroupMemberVo vo = new ShowGroupMemberVo();
        vo.setType(userAndGroup.getType());
        vo.setGid(userAndGroup.getGid());
        vo.setMembers(members);
        return vo;
    }
    
    @Override
    public ResponseVo findByGid(String gid)
    {
        List<MineVo> mineVos = userAndGroupService.findByGid(gid);
        return buildInitVo(mineVos);
    }
    
    @Override
    public List<MineVo> findBy(String gid)
    {
        List<MineVo> mineVos = userAndGroupService.findByGid(gid);
        return mineVos;
    }
    
    @Override
    public List<Group> findByUid(String uid)
    {
        List<Group> groups = new ArrayList<Group>();
        List<UserAndGroup> userAndGroups = userAndGroupService.findByUid(uid);
        for (UserAndGroup userAndGroup : userAndGroups)
        {
            Group group = groupDao.findById(userAndGroup.getGid());
            groups.add(group);
        }
        return groups;
    }
    
    // 根据条件搜索群组分页结果
    @Override
    public List<SearchGroupResultVo> search(GroupSearchCondition condition, int pageNum, int pageSize, String id)
    {
        int startNum = (pageNum - 1) * pageSize;
        int endNum = (pageNum - 1) * pageSize + pageSize - 1;
        List<Group> groups = groupDao.search(condition.getCondition(), startNum, endNum);
        List<UserAndGroup> userAndGroups = userAndGroupService.findByUid(id);
        List<SearchGroupResultVo> vos = new ArrayList<SearchGroupResultVo>();
        for (Group group : groups)
        {
            boolean alreadyAdd = false;
            for (UserAndGroup userAndGroup : userAndGroups)
            {
                if (group.getId().equals(userAndGroup.getGid()))
                {
                    alreadyAdd = true;
                }
            }
            SearchGroupResultVo vo = new SearchGroupResultVo();
            vo.setAvatar(group.getAvatar());
            vo.setId(group.getId());
            vo.setName(group.getName());
            vo.setNo(group.getNo());
            vo.setAlreadyAdd(alreadyAdd == false ? 0 : 1);
            vos.add(vo);
        }
        return vos;
    }
    
    // 根据条件搜索群组总条数
    @Override
    public int getSearchNum(GroupSearchCondition condition)
    {
        return groupDao.getSearchNum(condition.getCondition());
    }
    
    @Override
    public Group getByGid(String gid)
    {
        return groupDao.getByGid(gid);
    }
    
    @Override
    @Transactional
    public void delGroup(String gid) throws Exception
    {
        Group group = groupDao.getByGid(gid);
        groupDao.deleteByPrimaryKey(group.getNo());
        List<User> users = userAndGroupService.findByGroupId(gid);
        for (User user : users)
        {
            Notify notify = new Notify();
            notify.setDateTime(BasicUtil.getDateTime());
            notify.setUid(user.getId());
            notify.setContent("群组" + gid + "已解散,你已退出该群");
            notify.setIsRead(ReadStatus.UNREAD.value);
            notify.setFromUid(user.getId());
            notifyDao.insertSelective(notify);
        }
        userAndGroupService.deleteByGid(gid);
        notifyGroupDao.deleteByGid(gid);
    }
    
    @Override
    @Transactional
    public void delMember(String uid, String gid) throws Exception
    {
        userAndGroupService.deleteByUidAndGid(uid, gid);
        Notify notify = new Notify();
        notify.setDateTime(BasicUtil.getDateTime());
        notify.setUid(uid);
        notify.setContent("你已被群组" + gid + "踢出");
        notify.setIsRead(ReadStatus.UNREAD.value);
        notify.setFromUid(uid);
        NotifyGroup notifyGroup = new NotifyGroup();
        notifyGroup.setContent(uid + "已被踢出该群");
        notifyGroup.setGid(gid);
        notifyGroup.setFromUid(uid);
        notifyGroup.setIsRead(ReadStatus.UNREAD.value);
        notifyGroup.setDateTime(BasicUtil.getDateTime());
        notifyGroup.setType(ApplyStatus.SYS.value);
        notifyGroupDao.insertSelective(notifyGroup);
        notifyDao.insertSelective(notify);
    }
    
    @Override
    @Transactional
    public void quitGroup(String uid, String gid) throws Exception
    {
        userAndGroupService.deleteByUidAndGid(uid, gid);
        Notify notify = new Notify();
        notify.setDateTime(BasicUtil.getDateTime());
        notify.setUid(uid);
        notify.setContent("你已退出群组" + gid);
        notify.setIsRead(ReadStatus.UNREAD.value);
        notify.setFromUid(uid);
        NotifyGroup notifyGroup = new NotifyGroup();
        notifyGroup.setContent(uid + "已退出该群");
        notifyGroup.setGid(gid);
        notifyGroup.setFromUid(uid);
        notifyGroup.setIsRead(ReadStatus.UNREAD.value);
        notifyGroup.setDateTime(BasicUtil.getDateTime());
        notifyGroup.setType(ApplyStatus.SYS.value);
        notifyGroupDao.insertSelective(notifyGroup);
        notifyDao.insertSelective(notify);
    }
    
    private ResponseVo buildInitVo(List<MineVo> mineVos)
    {
        ResponseVo responseVo = new ResponseVo();
        MemberVo memberVo = new MemberVo();
        memberVo.setList(mineVos);
        responseVo.setCode(0);
        responseVo.setMsg("");
        responseVo.setData(memberVo);
        return responseVo;
    }
    
}
